<template>
  <a-card class="general-card" title="OSS资源" :bordered="false">
    <searchTable
      :columns="columnsSearch"
      @reset="
        (val) => {
          apiParams = { ...apiParams, ...val, pageNumber: 1 };
        }
      "
      @search="
        (val) => {
          apiParams = { ...apiParams, ...val, pageNumber: 1 };
        }
      "
    ></searchTable>
    <a-row class="oss-manage">
      <div>
        <div class="file-list">
          <a-tree :data="treeData" @select="treeSelect">
            <template #switcher-icon="node, { isLeaf }">
              <template v-if="node.key === '0'"><IconDriveFile /></template>
              <IconDown v-if="!isLeaf" />
            </template>
            <template #extra="nodeData">
              <a-dropdown @select="onIconClick($event, nodeData)" v-if="nodeData.key !== '0'">
                <icon-more style="position: absolute; right: 16px; font-size: 22px; top: 5px; color: #999999;"/>
                <template #content>
                  <a-doption value="edit">编辑</a-doption>
                  <a-doption value="delete">删除</a-doption>
                </template>
              </a-dropdown>
              <!--<IconPlus style="position: absolute; right: 8px; font-size: 12px; top: 10px; color: #3370ff;" @click="() => onIconClick(nodeData)"/>-->
            </template>
          </a-tree>
          <div class="btnBox">
            <a-button long @click="handleClickAddGroup('ADD')">添加分组</a-button>
          </div>
        </div>
      </div>
      <div>
        <div class="pic-list">
          <div class="search-box">
            <a-dropdown :popup-max-height="false">
              <a-button>更多操作 <icon-down /></a-button>
              <template #content>
                <a-doption @click="() => init(apiParams, 'refresh')">刷新</a-doption>
                <a-doption @click="removeAll">批量删除</a-doption>
              </template>
            </a-dropdown>
            <uploadPicInput :data-list="{ directoryPath: apiParams.fileDirectoryId }" style="margin-left: 20px" @onSuccess="() => init(apiParams)"/>
            <!--<a-input v-model="apiParams.name" :style="{width:'320px'}" placeholder="查询图片名称" allow-clear @change="()=>init(apiParams)">-->
            <!--<template #suffix>-->
            <!--<icon-search />-->
            <!--</template>-->
            <!--</a-input>-->
          </div>
          <a-checkbox-group
            v-model="selectedOss"
            :default-value="selectedOss"
            @change="selectOssChange"
          >
            <div class="img-box">
              <div
                v-for="(item, index) in ossFileList"
                :key="index"
                class="img-item"
              >
                <a-checkbox :value="item.id">
                  <template #checkbox="{ checked }">
                    <div
                      class="card"
                      :class="{ 'custom-checkbox-card-checked': checked }"
                      @mouseover="mouseOver(item)"
                      @mouseleave="mouseLeave(item)"
                    >
                      <div className="custom-checkbox-card-mask"
                        ><div className="custom-checkbox-card-mask-dot"
                      /></div>
                      <img :src="item.url" alt="" />
                      <!--<a-image :src="item.url" alt="无效的图片链接"></a-image>-->
                      <div v-if="item.isShowPreview" class="preview">
                        <div @click.prevent="previewEditClick($event, item)"
                          ><a-tooltip content="下载"
                            ><icon-cloud-download size="16" /></a-tooltip
                        ></div>
                        <div @click.prevent="previewDeleteClick($event, item)"
                          ><a-tooltip content="删除"
                            ><icon-delete size="16" /></a-tooltip
                        ></div>
                        <div @click.prevent="previewEyeClick($event, item)"
                          ><a-tooltip content="预览"
                            ><icon-eye size="16" /></a-tooltip
                        ></div>
                      </div>
                    </div>
                  </template>
                </a-checkbox>
                <div class="text">
                  <a-tooltip :content="item.name"
                    ><div>{{ item.name }}</div></a-tooltip
                  >
                </div>
              </div>
            </div>
          </a-checkbox-group>
          <div class="pagination-box">
            <a-pagination
              :current="apiParams.current"
              :total="apiParams.total"
              :page-size="apiParams.pageSize"
              @change="paginationChange"
            />
          </div>
        </div>
      </div>
    </a-row>

    <!-- 编辑文件名 -->
    <a-modal :width="550" v-model:visible="modalVisible">
      <template #title> 编辑文件名 </template>
      <a-form ref="formRef" :model="form">
        <a-form-item field="name" label="原文件名" :rules="[REQUIRED]">
          <a-input v-model="form.name"></a-input>
        </a-form-item>
        <a-form-item field="fileKey" label="存储文件名" :rules="[REQUIRED]">
          <a-input v-model="form.fileKey" disabled></a-input>
        </a-form-item>
      </a-form>
      <template #footer>
        <div style="text-align: right">
          <a-button style="margin-right: 5px" @click="modalVisible = false">取消</a-button>
          <a-button type="primary"  @click="handleSubmit">提交</a-button>
        </div>
      </template>
    </a-modal>
    <!-- 添加/编辑分组模态框 -->
    <a-modal :width="500" v-model:visible="enableGroupVisible">
      <template #title>{{groupFormType==='ADD'?'添加分组':'编辑分组'}}</template>
      <a-form ref="groupFormRef" :model="groupForm">
        <a-form-item field="id" label="所在分组" :rules="[REQUIRED]">
          <a-tree-select :data="treeData" :label-in-value="true" :default-value="defaultValue" v-model:model-value="defaultValue"
                         placeholder="Please select ..." @change="treeSelectChange" tree-checked-strategy="all"></a-tree-select>
        </a-form-item>
        <a-form-item field="directoryName" label="分组名称" :rules="[REQUIRED]">
          <a-input v-model="groupForm.directoryName"></a-input>
        </a-form-item>
      </a-form>
      <template #footer>
        <div style="text-align: right;">
          <a-button style="margin-right: 5px" @click="enableGroupVisible = false">取消</a-button>
          <a-button type="primary" :loading="groupLoading" @click="groupFormSubmit">提交</a-button>
        </div>
      </template>
    </a-modal>
    <!-- 预览图片 -->
    <a-modal v-model:visible="picVisible" title="查看图片" draggable>
      <a-image :src="file.url" width="100%" alt="无效的图片链接"></a-image>
      <template #footer>
        <span>文件类型：{{ file.fileType }} 文件大小：{{ file.msize }}</span>
      </template>
    </a-modal>
  </a-card>
</template>

<script lang="ts" setup>
  import searchTable from '@/components/search-column/index.vue';
  import {
    onMounted,
    ref,
    nextTick,
    inject,
    h,
    reactive,
    watch,
  } from 'vue';
  import {
    IconDriveFile,
    IconDown,
    IconStar,
    IconUp,
  } from '@arco-design/web-vue/es/icon';
  import { getFileDirectory, getFileListData, deleteFile, addFileDirectory, updateFileDirectory, delFileDirectory, renameFile } from '@/api/common';
  import uploadPicInput from '@/components/upload-pic/index.vue';
  import useCurrentInstance from '@/hooks/useCurrentInstance';
  import { Message } from '@arco-design/web-vue';
  import { REQUIRED } from '@/utils/validator';
  import { FormInstance } from '@arco-design/web-vue/es/form';
  import { SearchRule, MethodsRule, ColumnsDataRule } from '@/types/global';

  const groupLoading = ref<boolean>(false);
  //  获取modal
  const modal = useCurrentInstance().globalProperties?.$modal;
  const selectedKey = ref(['0']);
  const treeData = ref<any>();
  const ossFileList = ref<any>([]);
  // 传递的参数
  const apiParams = ref<any>({
    // 搜索框对应data对象
    fileType: 'image',
    pageNumber: 1, // 当前页数
    pageSize: 27, // 页面大小
    sort: 'createTime', // 默认排序字段
    order: 'desc', // 默认排序方式
    startTime: '', // 起始时间
    endTime: '', // 终止时间
    title: '',
    total: 0,
    current: 1,
    fileDirectoryId: '',
    name: '',
  });
  const thumbnailParameter = JSON.parse(
    JSON.stringify({ ...apiParams.value, pageSize: 15 })
  );
  const selectedOss = ref([]);
  const emit: any = defineEmits<{
    (e: 'selected', val: any, type: string): void;
  }>();
  const picVisible = ref(false); // 图片的modal
  const file = ref<any>({}); // 文件数据
  const columnsSearch: Array<SearchRule> = [
    {
      label: '图片名称',
      model: 'name',
      disabled: false,
      input: true,
    },
  ];
  const defaultValue = ref();

  const modalVisible = ref<boolean>(false) // 弹框是否显示
  const form = ref({ // 表单
    name: '',
    fileKey: '',
    id: '',
    oldKey: '',
  })
  const oldKey = ref<string>('') // 请求参数
  const enableGroupVisible = ref<boolean>(false); // 添加/编辑分组模态框
  const groupFormType = ref('ADD');
  const groupForm = ref<any>({
    id: '0',
    directoryName: '',
  });
  const groupFormRef = ref<any>();
  const formRef = ref<any>();

  // 文件目录格分类式化方法
  const getTree = (tree = []) => {
    const arr:any = [];
    if (!!tree && tree.length !== 0) {
      // :field-names="{ children: 'children', title: 'directoryName', key: 'id' }"
      tree.forEach((item:any) => {
        const obj:any = {};
        obj.title = item.directoryName;
        obj.key = item.id; // 拥有者id
        obj.type = item.directoryType; // 用户类型
        obj.label = item.directoryName;
        obj.level = item.level;
        obj.expand = false;
        obj.selected = false;
        obj.contextmenu = true;
        obj.parentId = item.parentId;
        obj.children = getTree(item.children);
        obj.icon = () => h(IconDriveFile);
        arr.push(obj);
      });
    }
    return arr;
  };
  // 获取文件列表
  const getFileList = () => {
    getFileDirectory().then((res) => {
      if (res.data.success) {
        treeData.value = getTree(res.data.result);
        treeData.value.unshift({
          title: '我的图片',
          label: '我的图片',
          value: '0',
          level: 0,
          children: [],
          id: '0',
          categoryId: 0,
          key: '0',
          // icon: () => h(IconDriveFile)
        });
      }
    });
  };
  // oss资源请求接口
  const init = async (params = apiParams.value, type: any = null) => {
    const res = await getFileListData(params);
    if (res.data.success) {
      res.data.result.records.forEach((item) => {
        item.selected = false;
      });
      ossFileList.value = res.data.result.records.map((item) => {
        item.isShowPreview = false;
        return item;
      });
      const { current, size, total } = res.data.result;
      apiParams.value.current = current;
      apiParams.value.pageSize = size;
      apiParams.value.total = total;
      if (type === 'refresh') {
        Message.success('刷新成功！');
      }
    }
  };
  // 分页改变
  const paginationChange = (v) => {
    apiParams.value = { ...apiParams.value, pageNumber: v };
  };
  // 复选框值改变时触发
  const selectOssChange = (value) => {
    emit('selected', selectedOss.value);
  };
  const mouseOver = (item) => {
    item.isShowPreview = true;
  };
  const mouseLeave = (item) => {
    item.isShowPreview = false;
  };
  // 编辑图片名称
  const previewEditClick = (event, v: any) => {
    event.stopPropagation();
    window.open(
      `${v.url}?attname=&response-content-type=application/octet-stream`
    );
  };
  // 删除图片
  const previewDeleteClick = (event, v: any) => {
    event.stopPropagation();
    modal.confirm({
      title: '确认删除',
      content: `您确认要删除文件${v.name}?`,
      alignCenter: false,
      onOk: async () => {
        const res = await deleteFile(v.id);
        if (res.data.success) {
          Message.success(`删除文件${v.name}成功`);
          init();
        }
      },
    });
  };
  // 批量删除
  const removeAll = () => {
    if (selectedOss.value.length <= 0) {
      Message.warning('您还未选择要删除的数据');
      return;
    }
    modal.confirm({
      title: '确认删除',
      content: `您确认要删除所选的${selectedOss.value.length}个文件?`,
      alignCenter: false,
      onOk: async () => {
        let ids = '';
        selectedOss.value.forEach((e: any) => {
          ids += `${e},`;
        });
        ids = ids.substring(0, ids.length - 1);
        const res = await deleteFile(ids);
        if (res.data.success) {
          Message.success('批量删除文件成功');
          selectedOss.value = [];
          init();
        }
      },
    });
  };
  // 预览图片
  const previewEyeClick = (event, v: any) => {
    event.stopPropagation();
    file.value = v;
    file.value.msize = `${((v.fileSize * 1.0) / (1024 * 1024)).toFixed(2)}MB`;
    picVisible.value = true;
  };

  // 添加/修改目录
  const handleClickAddGroup = (type) => {
    enableGroupVisible.value = true;
    groupFormType.value = type;
    if (type === 'ADD') {
      groupForm.value = {id: '0', directoryName: '', parentId: '0'};
      defaultValue.value = { value: '0' };
    }
  };
  // 添加/修改分组模态框
  const treeSelectChange = (val) => {
    groupForm.value.parentId = val.value;
  };
  // 添加/修改分组提交
  const groupFormSubmit =  async () => {
    const auth = await groupFormRef.value?.validate();
    if (!auth) {
      groupLoading.value = true;
      const params = {...groupForm.value};
      params.level = params.parentId == '0' ? 0 : 1;
      let res;
      if (groupFormType.value === 'ADD') {
        // 添加
        delete params.id;
        res = await addFileDirectory(params);
      } else {
        // 修改
        res = await updateFileDirectory(params);
      }
      groupLoading.value = false;
      if (res.data.success) {
        Message.success('操作成功！');
        enableGroupVisible.value = false;
        getFileList();
      }
    }
  };
  // 删除分组
  const groupFormDelete = (key) => {
    modal.confirm({
      title: '确认删除',
      content: `是否删除该分组？`,
      alignCenter: false,
      onOk: async () => {
        delFileDirectory(key).then(res => {
          if (res.data.success) {
            Message.success('删除成功！');
            getFileList();
          }
        })
      }
    })
  }
  // 操作文件目录列表
  const onIconClick = (event, nodeData) => {
    if (event === 'edit') {
      handleClickAddGroup('EDIT');
      groupForm.value.directoryName = nodeData.label;
      groupForm.value.id = nodeData.key;
      groupForm.value.level = nodeData.level;
      groupForm.value.parentId = nodeData.parentId;
      // defaultValue.value = { value: nodeData.parentId, label: nodeData.label };
      defaultValue.value = { value: nodeData.parentId };
    }
    if (event === 'delete') {
      groupFormDelete(nodeData.key);
    }
  };
  // 选择目录回调
  const treeSelect = (selectedKeys:any, data:any) => {
    const id = selectedKeys[selectedKeys.length - 1];
    if (id === '0' || id == 0) {
      delete apiParams.value.fileDirectoryId;
    } else {
      apiParams.value.fileDirectoryId = id;
    }
  };
  // 提交
  const handleSubmit = async () => {
    const params = {
      id: form.value.id,
      key: oldKey.value,
      newKey: form.value.fileKey,
      newName: form.value.name
    }
    const auth = await formRef.value?.validate();
    if (!auth) {
      const res = await renameFile(params)
      if (res.data.success) {
        Message.success('操作成功');
        modalVisible.value = false
        // tablePageRef.value.init();
      }
    }
  }

  onMounted(() => {
    // 获取文件列表
    getFileList();
    init();
  });
  // 初始化监听
  watch(
    () => [apiParams.value],
    (val) => {
      init();
    },
    { deep: true }
  );
</script>

<style lang="less" scoped>
  .oss-manage {
    /*height: 632px;*/
    width: 100%;
    display: flex;
    flex-wrap: nowrap;
    align-content: stretch;
    > div:nth-of-type(1) {
      width: 200px;
      flex-shrink: 0;
      align-self: stretch;
    }
    > div:nth-of-type(2) {
      width: 100%;
    }
  }
  // 文件列表
  .file-list {
    height: 100%;
    box-sizing: border-box;
    border-right: 1px solid #e5e6eb;
    padding: 0 0 24px;
  }
  // 图片列表
  .pic-list {
    height: 100%;
    box-sizing: border-box;
    padding: 0 0 24px 0;
  }
  .search-box {
    display: flex;
    /*flex-direction: row-reverse;*/
    /*justify-content: space-between;*/
    justify-content: flex-end;
  }
  .img-box {
    width: 100%;
    /*height: 500px;*/
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: flex-start;
    align-content: flex-start;
    margin-top: 20px;
    .img-item {
      width: 120px;
      height: 158px;
      box-sizing: border-box;
      /*margin: 0 26px 8px 0;*/
      margin: 0 13px 8px;
      .card {
        width: 120px;
        height: 120px;
        border-radius: 8px;
        border: 2px solid transparent;
        overflow: hidden;
        box-sizing: border-box;
        position: relative;
        img {
          width: 100%;
          height: 100%;
        }
        .checkbox {
          position: absolute;
          top: 10px;
          right: 10px;
          z-index: 1000;
        }
        .preview {
          width: 100%;
          height: 26px;
          background-color: #ffffff;
          text-align: center;
          line-height: 30px;
          color: #666666;
          position: absolute;
          left: 0;
          bottom: 0;
          display: flex;
          flex-wrap: nowrap;
          > div {
            width: 100%;
            flex: 1;
          }
        }
      }
      .card:hover,
      .custom-checkbox-card-checked {
        border: 2px solid #1966ff;
      }
      .text {
        width: 120px;
        height: 36px;
        align-items: center;
        display: flex;
        justify-content: center;
        cursor: pointer;
        div {
          color: #252931;
          font-size: 14px;
          line-height: 36px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }
  .pagination-box {
    display: flex;
    flex-direction: row-reverse;
  }

  .custom-checkbox-card {
    border: 1px solid var(--color-border-2);
    border-radius: 4px;
    width: 40px;
    height: 40px;
    box-sizing: border-box;
    position: relative;
  }

  .custom-checkbox-card-mask {
    height: 14px;
    width: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 2px;
    border: 1px solid var(--color-border-2);
    box-sizing: border-box;
    position: absolute;
    top: 10px;
    right: 10px;
    background-color: #ffffff;
  }

  .custom-checkbox-card-mask-dot {
    width: 8px;
    height: 8px;
    border-radius: 2px;
  }

  .custom-checkbox-card-title {
    color: var(--color-text-1);
    font-size: 14px;
    font-weight: bold;
    margin-bottom: 8px;
  }

  .custom-checkbox-card:hover,
  .custom-checkbox-card-checked,
  .custom-checkbox-card:hover .custom-checkbox-card-mask,
  .custom-checkbox-card-checked .custom-checkbox-card-mask {
    border-color: rgb(var(--primary-6));
  }

  .custom-checkbox-card-checked {
    background-color: var(--color-primary-light-1);
  }

  .custom-checkbox-card:hover .custom-checkbox-card-title,
  .custom-checkbox-card-checked .custom-checkbox-card-title {
    color: rgb(var(--primary-6));
  }

  .custom-checkbox-card-checked .custom-checkbox-card-mask-dot {
    background-color: rgb(var(--primary-6));
  }
  :deep(.arco-tree-node-selected) {
    background-color: #f2f3f5;
  }
  :deep(.arco-tree-node) {
    height: 36px;
    color: #19191a;
    font-size: 14px;
  }
  :deep(.arco-tree-node:hover) {
    background-color: #f2f3f5;
  }
</style>
